package cn.buk.tms.dto.response;

import cn.buk.common.util.DecimalUtil;
import cn.buk.tms.entity.order.hotel.HotelOrder;
import cn.buk.tms.entity.order.hotel.HotelOrderPassenger;
import cn.buk.tms.entity.order.hotel.HotelOrderPrice;
import cn.buk.tms.common.dto.hotel.BaseHotelOrderDto;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.hotel.dto.HotelOrderPassengerDto;
import cn.buk.tms.hotel.dto.HotelOrderPriceDto;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.beans.BeanUtils;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 酒店订单DTO
 * Created by yfdai on 2020-05-10
 * @author yfdai
 */
public class HotelOrderResponseDto extends BaseHotelOrderDto {

    public static HotelOrderResponseDto createByHotelOrder(HotelOrder o) {
        HotelOrderResponseDto dto = new HotelOrderResponseDto();
        BeanUtils.copyProperties(o, dto, "passengers", "prices");

        //订单状态
        dto.setOrderStatus(o.getStatus());
        //价格校验状态
        dto.setPriceCheckedStatus(o.getPriceChecked());
        dto.setPriceCheckedTime(o.getPriceCheckedTime());
        //审批相关信息
        if (o.getApprovalInfo() != null) {
            dto.setSpecifiedApprover(o.getApprovalInfo().getSpecifiedApprover());
            dto.setApprovalStatus(o.getApprovalInfo().getApprovalStatus());
            dto.setApprovalDenyReason(o.getApprovalInfo().getApprovalDenyReason());
            dto.setViolationStatus(o.getApprovalInfo().getViolationStatus());
            dto.setViolationReason(o.getApprovalInfo().getViolationReason());
        }

        dto.setPassengers(new ArrayList<>());
        String psgNames = null;

        for (HotelOrderPassenger psg : o.getPassengers()) {

            HotelOrderPassengerDto psgDto = new HotelOrderPassengerDto();

            BeanUtils.copyProperties(psg, psgDto);

            dto.getPassengers().add(psgDto);

            if (psgNames == null) {
                psgNames = psg.getName();
            } else {
                psgNames += "," + psg.getName();
            }
        }

        if (psgNames != null) {
            dto.setPsgCount(dto.getPassengers().size());
            dto.setPassengerName(psgNames);
        }

        if (o.getCustomer() == null) {
            dto.setCustomerId(0);
            dto.setCustomerName("散客");
        } else {
            dto.setCustomerId(o.getCustomerId());
            dto.setCustomerName(o.getCustomer().getVipName());
            dto.setCustomerCode(o.getCustomer().getCustomerCode());
        }

        if (o.getSupplier() != null) {
            dto.setSupplierId(o.getSupplier().getId());
            dto.setSupplierName(o.getSupplier().getName());
        }

        if (o.getPaymentMethod() != null) {
            dto.setPaymentMethodId(o.getPaymentMethod().getId());
            dto.setPaymentMethodName(o.getPaymentMethod().getName());
        }

        for(HotelOrderPrice price: o.getPrices()) {
            HotelOrderPriceDto priceDto = new HotelOrderPriceDto();
            BeanUtils.copyProperties(price, priceDto);

            dto.getPrices().add(priceDto);
        }

        return dto;
    }

    private String operator;

    private String ticketer;

    /**
     * 上级酒店订单号, 用来关联
     */
    private String parentOrderNo;

    /**
     * 预订渠道
     * 0 - 人工
     * 1 - 携程代理通
     */
    private Integer reservationChannel;

    /**
     * 供应商订单号
     */
    private String supplierOrderNo;
    /**
     * 供应商订单状态
     */
    private int supplierOrderStatus;

    /**
     * 供应商的订单确认方式
     * 1：按入住人入住
     * 2：按确认号入住
     */
    private int supplierConfirmType;

    /**
     * 供应商提供的订单确认号
     */
    private String supplierConfirmNo;

    /**
     * 供应商提供的拒绝类型
     * 1：满房
     * 2：房价不对
     * 3：其他原因
     */
    private int supplierRejectType;

    /**
     * 供应商提供的拒单的原因
     */
    private String supplierRejectReason;

    /**
     * 供应商订单中的备注
     */
    private String supplierRemark;

    /**
     * 联系人
     */
    private String linkman;

    /**
     * 联系电话
     */
    private String contactPhone;


    private int enterpriseId;







    //姓名 入住日期 酒店名称 房型 价格 服务费
    /**
     * 姓名
     */
    @NotNull
    @Size(min = 2, max = 50)
    private String passengerName;

    /**
     * 入住人数
     */
    private int psgCount;

    /**
     * 入住人信息
     */
    @NotNull
    @Size(min = 1, max = 1000)
    private List<HotelOrderPassengerDto> passengers = new ArrayList<>();

    /**
     * 酒店名称
     */
    @NotNull
    @Size(min = 2, max = 100)
    private String hotelName;

    /**
     * 本地酒店系统中的酒店id
     */
    private int hotelId;

    /**
     * 房型
     */
    @NotNull
    @Size(min = 1, max = 150)
    private String roomType;

    /**
     * 本地酒店系统中的售卖房型id
     */
    private int roomId;

    /**
     * 房间数
     */
    @Min(1)
    private int roomCount;

    /**
     * 入住日期
     */
    @NotNull
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    private Date checkInDate;

    /**
     * 离店日期
     */
    @NotNull
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    private Date checkOutDate;

    /**
     * 价格/间夜
     */
    private double price;

    /**
     * 底价/间夜
     */
    private Double bottomPrice;

    /**
     * 服务费
     */
    private double serviceCharge;

    /**
     * 间夜数(房间数*天数）
     */
    @NotNull
    @Min(1)
    private Integer count;

    /**
     * 实收客户总额
     */
    private Double totalAmount;

    /**
     * 总成本
     */
    private Double totalCost;

    /**
     * 利润
     */
    private Double profit;

    /**
     * 每日价格
     */
    @NotNull
    @Size(max = 1000)
    private List<HotelOrderPriceDto> prices = new ArrayList<>();

    /**
     * 最晚到店时间
     */
    private String lastArriveTime;

    private String remark;

    /**
     * 是否已付款
     */
    private String bePaid;

    /**
     * 供应商ID
     */
    private int supplierId;

    /**
     * 供应商名称
     */
    private String supplierName;

    /**
     * 付款方式ID
     */
    private int paymentMethodId;

    /**
     * 付款方式名称
     */
    private String paymentMethodName;

    /**
     * 保存数据库的时间：系统自动生成
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date lastUpdate;


    /**
     * 计算价格
     */
    public void calc() {
        final int days = DateUtil.getPastDays(this.checkOutDate, this.checkInDate);
        this.count = days * this.roomCount;
        this.totalAmount = this.count * this.price;
        this.totalCost = this.count * this.bottomPrice;
        this.profit = this.totalAmount - this.totalCost + this.serviceCharge;
    }


    public int getEnterpriseId() {
        return enterpriseId;
    }

    public void setEnterpriseId(int enterpriseId) {
        this.enterpriseId = enterpriseId;
    }

    public String getPassengerName() {
        return passengerName;
    }

    public void setPassengerName(String passengerName) {
        this.passengerName = passengerName;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getServiceCharge() {
        return serviceCharge;
    }

    public void setServiceCharge(double serviceCharge) {
        this.serviceCharge = serviceCharge;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public void setHotelName(String hotelName) {
        this.hotelName = hotelName;
    }

    public void setRoomType(String roomType) {
        this.roomType = roomType;
    }

    public String getRoomType() {
        return roomType;
    }

    public String getHotelName() {
        return hotelName;
    }

    public String getBePaid() {
        return bePaid;
    }

    public void setBePaid(String bePaid) {
        this.bePaid = bePaid;
    }

    public int getRoomCount() {
        return roomCount;
    }

    public void setRoomCount(int roomCount) {
        this.roomCount = roomCount;
    }

    public Double getBottomPrice() {
        return bottomPrice;
    }

    public void setBottomPrice(Double bottomPrice) {
        this.bottomPrice = bottomPrice;
    }

    public int getCount() {
        return count == null ? 1 : count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public double getTotalAmount() {
        return totalAmount == null ? 0 : totalAmount;
    }

    public void setTotalAmount(Double totalAmount) {
        this.totalAmount = totalAmount;
    }

    public double getTotalCost() {
        return totalCost == null ? 0 : DecimalUtil.keepScale2(totalCost);
    }

    public void setTotalCost(Double totalCost) {
        this.totalCost = totalCost;
    }

    public double getProfit() {
        return profit == null ? 0 : DecimalUtil.keepScale2(profit);
    }

    public void setProfit(Double profit) {
        this.profit = profit;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public Date getCheckInDate() {
        return checkInDate;
    }

    public void setCheckInDate(Date checkInDate) {
        this.checkInDate = checkInDate;
    }

    public Date getCheckOutDate() {
        return checkOutDate;
    }

    public void setCheckOutDate(Date checkOutDate) {
        this.checkOutDate = checkOutDate;
    }


    public int getSupplierId() {
        return supplierId;
    }

    public void setSupplierId(int supplierId) {
        this.supplierId = supplierId;
    }

    public String getSupplierName() {
        return supplierName;
    }

    public void setSupplierName(String supplierName) {
        this.supplierName = supplierName;
    }

    public int getPaymentMethodId() {
        return paymentMethodId;
    }

    public void setPaymentMethodId(int paymentMethodId) {
        this.paymentMethodId = paymentMethodId;
    }

    public String getPaymentMethodName() {
        return paymentMethodName;
    }

    public void setPaymentMethodName(String paymentMethodName) {
        this.paymentMethodName = paymentMethodName;
    }


    public List<HotelOrderPassengerDto> getPassengers() {
        if (this.passengers == null) {
            this.passengers = new ArrayList<>();
        }
        return passengers;
    }

    public void setPassengers(List<HotelOrderPassengerDto> passengers) {
        this.passengers = passengers;
    }

    public int getPsgCount() {
        return psgCount;
    }

    public void setPsgCount(int psgCount) {
        this.psgCount = psgCount;
    }

    public int getHotelId() {
        return hotelId;
    }

    public void setHotelId(int hotelId) {
        this.hotelId = hotelId;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public List<HotelOrderPriceDto> getPrices() {
        if (prices == null) {
            prices = new ArrayList<>();
        }
        return prices;
    }

    public void setPrices(List<HotelOrderPriceDto> prices) {
        this.prices = prices;
    }

    public String getLastArriveTime() {
        return lastArriveTime;
    }

    public void setLastArriveTime(String lastArriveTime) {
        this.lastArriveTime = lastArriveTime;
    }

    public int getSupplierOrderStatus() {
        return supplierOrderStatus;
    }

    public void setSupplierOrderStatus(int supplierOrderStatus) {
        this.supplierOrderStatus = supplierOrderStatus;
    }

    public String getSupplierOrderNo() {
        return supplierOrderNo;
    }

    public void setSupplierOrderNo(String supplierOrderNo) {
        this.supplierOrderNo = supplierOrderNo;
    }

    public String getLinkman() {
        return linkman;
    }

    public void setLinkman(String linkman) {
        this.linkman = linkman;
    }

    public String getContactPhone() {
        return contactPhone;
    }

    public void setContactPhone(String contactPhone) {
        this.contactPhone = contactPhone;
    }

    public int getSupplierConfirmType() {
        return supplierConfirmType;
    }

    public void setSupplierConfirmType(int supplierConfirmType) {
        this.supplierConfirmType = supplierConfirmType;
    }

    public String getSupplierConfirmNo() {
        return supplierConfirmNo;
    }

    public void setSupplierConfirmNo(String supplierConfirmNo) {
        this.supplierConfirmNo = supplierConfirmNo;
    }

    public int getSupplierRejectType() {
        return supplierRejectType;
    }

    public void setSupplierRejectType(int supplierRejectType) {
        this.supplierRejectType = supplierRejectType;
    }

    public String getSupplierRejectReason() {
        return supplierRejectReason;
    }

    public void setSupplierRejectReason(String supplierRejectReason) {
        this.supplierRejectReason = supplierRejectReason;
    }

    public String getSupplierRemark() {
        return supplierRemark;
    }

    public void setSupplierRemark(String supplierRemark) {
        this.supplierRemark = supplierRemark;
    }

    public Integer getReservationChannel() {
        return reservationChannel;
    }

    public void setReservationChannel(Integer reservationChannel) {
        this.reservationChannel = reservationChannel;
    }

    public String getTicketer() {
        return ticketer;
    }

    public void setTicketer(String ticketer) {
        this.ticketer = ticketer;
    }

    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public String getParentOrderNo() {
        return parentOrderNo;
    }

    public void setParentOrderNo(String parentOrderNo) {
        this.parentOrderNo = parentOrderNo;
    }
}
